package com.msg;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;

import com.msg.handler.ProtoHandler;
import com.msg.server.MinaServer;
import com.msg.utils.MsgSrvUtils;
import com.pjc.db.MongoDB;
import com.pjc.db.RedisDB;
import com.pjc.rpc.LogicRpc;
import com.pjc.thrift.TAccessService;
import com.pjc.utils.ConfigUtil;
import com.pjc.utils.SystemUtil;

import org.apache.thrift.TProcessor;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.protocol.TCompactProtocol;

/**
 * 消息服务启动入口
 */
public class Shell {
	private static final Logger log = LoggerFactory.getLogger(Shell.class);

	private static int thriftPort = 9391;

	private static String redisHost = "";
	private static int redisPort;
	private static int redisDBIndex;
	private static String redisPwd = "";

	private static String logicSrvHost;
	private static int logicSrvPort;
	private static int logicSrvTimeout;
	private static int maxTotal;
	private static int maxIdle;

	public static void main(String[] args) throws Exception {
		try {			
			// 日志组件初始化
			initLogger();
			log.info("初始化config.properties文件......");
			if (ConfigUtil.getInstance().initConfig(Shell.class)) {

				log.info("初始化config.properties完成......");
				initConfig();
				log.info("扫描协议中......");
				MsgSrvUtils.getInstance().setUp();
				log.info("扫描协议完成......");

				log.info("Redis启动中......");
				RedisDB.getInstance().init(redisHost, redisPort,redisPwd,redisDBIndex);
				log.info("Redis启动成功......");

				log.info("Logic Srv客户端启动中......");
				LogicRpc.getInstance().init(logicSrvHost, logicSrvPort, logicSrvTimeout, maxTotal, maxIdle);
				log.info("Logic Srv客户端启动完成......");
				log.info("Mina Srv正在启动中......");
				MinaServer.Start();
				log.info("Mina Srv启动完成......");
				log.info("Thrift 服务正在监听中。监听端口：" + ConfigUtil.getInstance().getIntProperties("thrift.port", thriftPort) + "。");
				initThriftService();

			} else {
				log.error("配置文件及相关服务加载失败......");
			}

		} catch (Exception e) {
			log.error("消息服务启动异常!", e);
		}
	}

	/**
	 * 获取配置文件信息
	 * 
	 * @author 王畅
	 * @throws Exception
	 */
	private static void initConfig() throws Exception {

		MsgSrvUtils.serverId = ConfigUtil.getInstance().getIntProperties("server.id");
		MinaServer.port = ConfigUtil.getInstance().getIntProperties("server.msg.port");

		thriftPort = ConfigUtil.getInstance().getIntProperties("thrift.port", 9391);
		maxTotal = ConfigUtil.getInstance().getIntProperties("thriftPool.maxTotal", 200);
		maxIdle = ConfigUtil.getInstance().getIntProperties("thriftPool.maxIdle", 30);

		redisHost = ConfigUtil.getInstance().getStringProperties("db.redis.host");
		redisPort = ConfigUtil.getInstance().getIntProperties("db.redis.port");
		redisDBIndex = ConfigUtil.getInstance().getIntProperties("db.redis.dbindex", 1);
		redisPwd = ConfigUtil.getInstance().getStringProperties("db.redis.password");

		logicSrvHost = ConfigUtil.getInstance().getStringProperties("logicSrv.host");
		logicSrvPort = ConfigUtil.getInstance().getIntProperties("logicSrv.port");
		logicSrvTimeout = ConfigUtil.getInstance().getIntProperties("logicSrv.timeout", 30000);

		/****************** MongoDB初始化 **************************************************/
		String mongoHost = ConfigUtil.getInstance().getStringProperties("db.mongo.host");
		int mongoPort = ConfigUtil.getInstance().getIntProperties("db.mongo.port", 27017);
		String mongoDb = ConfigUtil.getInstance().getStringProperties("db.mongo.dbname");
		String mongoUser = ConfigUtil.getInstance().getStringProperties("db.mongo.user");
		String mongoPwd = ConfigUtil.getInstance().getStringProperties("db.mongo.password");
		MongoDB.init(mongoHost, mongoPort, mongoDb, mongoUser, mongoPwd);
	}

	/**
	 * 消息服务Thrift服务端监听启动
	 * 
	 * @throws TTransportException
	 */
	private static void initThriftService() throws TTransportException {

		TMultiplexedProcessor tprocessor = new TMultiplexedProcessor();
		TProcessor processor = new TAccessService.Processor<TAccessService.Iface>(new ProtoHandler());
		tprocessor.registerProcessor("accessService", processor);
		TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(thriftPort);
		TNonblockingServer.Args args = new TNonblockingServer.Args(tnbSocketTransport);
		args.processor(tprocessor);
		args.transportFactory(new TFramedTransport.Factory());
		args.protocolFactory(new TCompactProtocol.Factory());
		TServer server = new TNonblockingServer(args);
		server.serve();
	}

	/**
	 * 初始化日志服务组件
	 * 
	 * @author 王畅
	 */
	private static void initLogger() {
		LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
		JoranConfigurator configurator = new JoranConfigurator();
		configurator.setContext(lc);
		lc.reset();
		try {
			String path = SystemUtil.GetConfigPath(Shell.class, "logback.xml");
			configurator.doConfigure(path);
		} catch (JoranException e) {
			log.error("消息服务器日志文件启动异常!", e);
		}
		StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
	}

}
